/**
给予 mio 实现的 服务端
网络处理方式相同

*/


extern crate mio;
mod ProcRountMod;
use std::collections::HashMap;
use std::io::*;
use mio::net::{TcpListener, TcpStream};
use mio::{Token, Poll, Ready, PollOpt, Events};
use std::iter::Map;

fn main() {
    //创建一个Token
    const SERVER: Token = Token(0);
    let mut curr_client_id = 1;

    let mut key_map: HashMap<String, String> = HashMap::new();

    // 设置服务器地址
    let tcp_addr = "127.0.0.1:9000".parse().unwrap();
    //绑定 服务端地址 到 tcp监听器
    let tcp_server = TcpListener::bind(&tcp_addr).unwrap();
    // 创建poll 对象及配置
    let poll = Poll::new().unwrap();
    let pollopts = if cfg!(feature = "level") {
        PollOpt::level()
    } else {
        if cfg!(feature = "oneshot") {
            PollOpt::edge() | PollOpt::oneshot()
        } else {
            PollOpt::edge()
        }
    };

    // 注册 tcp 服务器 到 token
    poll.register(&tcp_server, SERVER, Ready::readable(), PollOpt::edge())
        .unwrap();

    // 创建储存事件读对象
    let mut events = Events::with_capacity(1024); // 设置事件容量大小
    let buf = &mut [0u8; 1024]; // socket buff
    let mut amt = 0; // 当前 读取的 buff 长度
    // 流存储map
    let mut streams = HashMap::new();//只要流保存了，TCP连接就不关闭，根据客户端的id取流
    // 主循环
    loop {
        poll.poll(&mut events, None).unwrap();
        // 迭代事件
        for event in events.iter() {
            match event.token() {
                SERVER => {
                    // 读取流
                    let (stream, _addr) = tcp_server.accept().unwrap();
                    let client_id = curr_client_id;
                    curr_client_id += 1;
                    let token = Token(client_id);
                    //将流存进streams map
                    if let Some(_stream) = streams.insert(client_id, stream) {
                        panic!("Stream entry token filled.");
                    }
                    // 注册一个新的事件 等待下一次 循环 取出 实件类型是可读
                    poll.register(&streams[&client_id], token, Ready::readable(), pollopts)
                        .unwrap();//为每一个新的TCP 客户端注册不同的token
                }
                // 客户端 任务 有 SERVER 事件注册 产生
                Token(client_id) => {
                    // 如果新的事件产生 会进入这里
                    if event.readiness().is_readable() {
                        // 事件是可读类型 进入这里，获取 客户端的流
                        let stream = streams.get_mut(&client_id).unwrap();
                        // 读取buff
                        match stream.read(buf) {
                            Ok(nread) => {
                                amt = nread;
                                //TODO
                                // println!("data buff = {:?}" , &buf);
                                ProcRountMod::proc_service(&streams, client_id, &poll, buf, amt, pollopts, &key_map);
                            }
                            Err(e) => println!("read err  {}", e),
                        }
                        println!("send ok ");
                    }
                    if event.readiness().is_writable() {
                        // 同理 可写事件进入这里
                        // 读取流
                        let mut stream = streams.get(&client_id).unwrap();//移除流TCP在stream生命周期结束后主动关闭
                        buf[0]=1;
                        buf[0]=0;
                        match stream.write(&buf[2..amt]) {
                            // 发送成功
                            Ok(nwrite) => println!("write  {} Bytes , data {:?}", nwrite, &buf[0..amt]),
                            Err(e) => println!("write err  {}", e),
                        }
                        poll.reregister(
                            stream,
                            Token(client_id),
                            Ready::readable(),
                            pollopts,
                        ).unwrap();//读完了 就开始准备写
                    }
                }
                // 其他事件
                _ => unreachable!(),
            }
        }
    }
}